/*
 * Client.java
 *
 * Created on 17. Januar 2003, 23:45
 */

package de.ama.view;

import de.ama.crawler.Config;
import de.ama.crawler.Entry;
import de.ama.crawler.Store;
import de.ama.search.WordIndex;
import de.ama.util.Util;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.List;

/**
 * @author Andreas Marochow
 */
public class AppWindow extends JFrame implements ActionListener {
    enum TagMode{show,tag,untag};

    protected EntryTableView tableView = null;
    protected EntryTableModel tableModel = null;
    private Dialog dialog = null;
    private String searchString = "";
    private String tagString = "all";
    private TagMode tagMode = TagMode.show;

    private JToolBar toolbar ;
    private JTextField searchField ;

    protected static AppWindow instance = null;

    public static AppWindow get() {
        return instance;
    }

    protected void initComponents() {
        setSize(850, 750);
        setIconImage(Util.loadIcon("icons/film_save.png").getImage());

        getContentPane().setBackground(Color.DARK_GRAY);
        tableView = new EntryTableView();
        tableModel = new EntryTableModel(Store.get().getAllEntries(), 8);
        tableView.setModel(tableModel);
        getContentPane().add(tableView, BorderLayout.CENTER);

        tableView.setClickHandler(new ClickHandler() {
            public void onClick(Entry e, MouseEvent me) {
                if (!Util.isEmpty(tagString) ) {
                    if(tagMode==TagMode.tag){
                        e.addTag(tagString);
                        sort();
                    } else if(tagMode==TagMode.untag){
                        e.removeTag(tagString);
                        sort();
                    } else if(tagMode==TagMode.show && me.getClickCount()==2){
                        showDetail(e);
                    }
                }
            }
        });

        tableView.getTable().addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (Store.get().isLoaded()) {
                    if (e.getKeyCode() == KeyEvent.VK_S && e.isControlDown()) {
                        Store.get().save();
                    }
                }
            }
        });

        buildPopupMenu();

        buildToolBar();

        refreshNorth();
    }


    private void buildToolBar() {
        toolbar = (JToolBar) initComponent(new JToolBar("Tagging"));
        toolbar.setFloatable(false);
        toolbar.setMargin(new Insets(0,0,0,0));
        toolbar.setBorder(null);
        toolbar.setMaximumSize(new Dimension(1200, 10));
        toolbar.setBorderPainted(false);

        List<String> actions = Config.get().getTags();
        actions.add("separator");
        actions.add("SHOW");
        actions.add("TAG");
        actions.add("UNTAG");
        for (String tag : actions) {
            if(tag.equals("separator")){
                toolbar.addSeparator();
                toolbar.addSeparator();
            } else {
                JButton button = (JButton) initComponent(new JButton(tag));
                button.addActionListener(this);
                button.setBorderPainted(false);
                button.setFocusPainted(false);
                toolbar.add(button, null);
            }
        }

        searchField = (JTextField) initComponent(new JTextField());
        searchField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                triggerSearch();
            }
        });
        searchField.setCaretColor(Color.WHITE);
        searchField.setMaximumSize(new Dimension(300,16));

        toolbar.addSeparator();
        toolbar.addSeparator();
        toolbar.add(searchField);

        getContentPane().add(toolbar, BorderLayout.NORTH);
    }

    private void triggerSearch() {
        if (Store.get().isLoaded()) {
            if(!searchField.getText().equals(searchString)){
                searchString = searchField.getText();
                if (Util.isEmpty(searchField.getText())) {
                    tableModel.setFilter(null);
                } else {
                    List<Integer> ids = WordIndex.get().findIds(searchString);
                    tableModel.setFilter(ids);
                }
                sort();
            }
            searchString = searchField.getText();
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        if(command.equalsIgnoreCase("show")) {
            tagMode = TagMode.show;
            setTag(tagString);
        } else if(command.equalsIgnoreCase("tag")) {
            tagMode = TagMode.tag;
            setTag(tagString);
        } else if(command.equalsIgnoreCase("untag")) {
            tagMode = TagMode.untag;
            setTag(tagString);
        } else {
            setTag(command);
        }
    }

    private Component initComponent(Component comp) {
        comp.setBackground(Color.DARK_GRAY);
        comp.setForeground(Color.LIGHT_GRAY);
        comp.setFont(new Font("Arial",Font.BOLD,12));
        return comp;
    }

    private void buildPopupMenu() {
        JPopupMenu menu = new JPopupMenu();
        Util.addMenuItem(menu, "start", "icons/arrow_right.png",new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                if (tableView.getSelected()!=null) {
                   startMovie(tableView.getSelected());
                }
            }
        });

        Util.addMenuItem(menu, "details", "icons/magnifier.png", new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                if (tableView.getSelected()!=null) {
                    showDetail(tableView.getSelected());
                }
            }
        });

        Util.addMenuItem(menu, "delete", "icons/delete.png",new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                if (tableView.getSelected()!=null) {
                    deleteFile(tableView.getSelected());
                }
            }
        });

        Util.addMenuItem(menu, "directory", "icons/folder.png", new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                if (tableView.getSelected()!=null) {
                    openDir(tableView.getSelected());
                }
            }
        });

        Util.addPopupMenu(tableView.getTable(), menu);
    }

    private void setTag(final String tag) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                tagString = tag;
                switch (tagMode){
                    case show:
                    case untag:
                        tableModel.setFilterTag(tag);
                        tableModel.setInverseFilterTag(null);
                        break;
                    case tag:
                        tableModel.setInverseFilterTag(tag);
                        tableModel.setFilterTag(null);
                        break;
                }
                sort();
            }
        });

    }

    public void sort() {
        tableModel.filterAndSort();
        refreshNorth();
    }

    public AppWindow() {
        instance = this;
        initGui();
        initComponents();
    }


    private void initGui() {

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                if (Store.get().isDirty()) {
                    if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(AppWindow.this, "Save Changes ?")) {
                        Store.get().save();
                    }
                }
                System.exit(0);
            }

        });

    }


    public void start() {
        setVisible(true);
    }


    public void showDetail(Entry e) {
        if (dialog == null) {
            dialog = new Dialog();
        }
        dialog.setDataToGui(e);
        dialog.setVisible(true);
    }

    public void showTitle(String title) {
        setTitle(title);
    }

    public void refreshNorth() {
        if (tableView != null) {
            setTitle("Movie Box [" + tableModel.getEntrys().size() + "/" + Store.get().getSize() + " titles]");
        }

        if(toolbar!=null){
            Component[] components = toolbar.getComponents();
            for(Component c: components){
                if (c instanceof JButton) {
                    JButton button = (JButton) c;
                    if(button.getActionCommand().equalsIgnoreCase(tagString)){
                       button.setForeground(new Color(204, 0, 0));
                    } else if(button.getActionCommand().equalsIgnoreCase(tagMode.name())){
                       button.setForeground(new Color(0, 204, 0));
                    } else {
                        button.setForeground(Color.LIGHT_GRAY);
                    }
                }
            }
        }
    }

    public EntryTableModel getTableModel() {
        return tableModel;
    }

    public void startMovie(Entry entry) {
        if (entry != null) {
            try {
                File file = new File(entry.getPath());
                File[] roots = File.listRoots();
                for (File root : roots) {
                    File movie = new File(root, file.getPath());
                    if (movie.exists()) {
                        Desktop.getDesktop().open(movie);
                        return;
                    }
                }
            } catch (Exception err) {
                err.printStackTrace();
            }
        }
    }

    public void openDir(Entry entry) {
        if (entry != null) {
            try {
                File[] roots = File.listRoots();
                for (File root : roots) {
                    File file = new File(root, entry.getPath());
                    if (file.exists() ) {
                        Desktop.getDesktop().open(file.getParentFile());
                        return;
                    }
                }
            } catch (Exception err) {
                err.printStackTrace();
            }
        }
    }

    public void deleteFile(Entry entry) {
        if (entry != null) {
            try {
                Store.get().removeEntry(entry);
                sort();

                File[] roots = File.listRoots();
                for (File root : roots) {
                    File file = new File(root, entry.getPath());
                    if (file.exists() ) {
                        if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(AppWindow.this, "realy delete "+file.getAbsolutePath())) {
                            file.delete();
                        }
                        return;
                    }
                }

            } catch (Exception err) {
                err.printStackTrace();
            }
        }
    }
}
